home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / Framewrk / FWPart / Sources / FWScrolr.cpp < prev    next >
Encoding:
Text File  |  1995-11-08  |  11.4 KB  |  369 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWScrolr.cpp
  4. //    Release Version:    $ 1.0d11 $
  5. //
  6. //    Copyright:    © 1993, 1995 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFrameW.hpp"
  11.  
  12. #ifndef FWSCROLR_H
  13. #include "FWScrolr.h"
  14. #endif
  15.  
  16. #ifndef FWPART_H
  17. #include "FWPart.h"
  18. #endif
  19.  
  20. #ifndef FWFRAME_H
  21. #include "FWFrame.h"
  22. #endif
  23.  
  24. #ifndef FWSCLNOT_H
  25. #include "FWSclNot.h"
  26. #endif
  27.  
  28. #ifndef FWITERS_H
  29. #include "FWIters.h"
  30. #endif
  31.  
  32. #ifndef FWUTIL_H
  33. #include "FWUtil.h"
  34. #endif
  35.  
  36. #ifndef FWSCLBAR_H
  37. #include "FWSclBar.h"
  38. #endif
  39.  
  40. // ----- OS Layer -----
  41.  
  42. #ifndef FWODGEOM_H
  43. #include "FWODGeom.h"
  44. #endif
  45.  
  46. // ----- OpenDoc Includes -----
  47.  
  48. #ifndef SOM_ODSession_xh
  49. #include <ODSessn.xh>
  50. #endif
  51.  
  52. #ifndef SOM_ODTransform_xh
  53. #include <Trnsform.xh>
  54. #endif
  55.  
  56. #ifndef SOM_ODWindow_xh
  57. #include <Window.xh>
  58. #endif
  59.  
  60. //========================================================================================
  61. // RunTime Info
  62. //========================================================================================
  63.  
  64. #if FW_LIB_EXPORT_PRAGMAS
  65. #pragma lib_export on
  66. #endif
  67.  
  68. #ifdef FW_BUILD_MAC
  69. #pragma segment FW_FrameSegment
  70. #endif
  71.  
  72. //========================================================================================
  73. // CLASS FW_CScroller
  74. //========================================================================================
  75.  
  76. //----------------------------------------------------------------------------------------
  77. // FW_CScroller::FW_CScroller
  78. //----------------------------------------------------------------------------------------
  79.  
  80. FW_CScroller::FW_CScroller(Environment* ev, FW_CView* view) :
  81.     FW_MReceiver(),
  82.     fView(view),
  83.     fConnection(this),
  84.     fScrollNotificationToken(0)
  85. {
  86.     ODSession* session = fView->GetFrame(ev)->GetPart(ev)->GetSession(ev);
  87.     fScrollNotificationToken = session->Tokenize(ev, FW_CScrollNotification::kName);
  88.  
  89.     fConnection.Connect();
  90. }
  91.  
  92. //----------------------------------------------------------------------------------------
  93. // FW_CScroller::~FW_CScroller
  94. //----------------------------------------------------------------------------------------
  95.  
  96. FW_CScroller::~FW_CScroller()
  97. {
  98. }
  99.  
  100. //----------------------------------------------------------------------------------------
  101. // FW_CScroller::RegisterScrollBar
  102. //----------------------------------------------------------------------------------------
  103.  
  104. void FW_CScroller::RegisterScrollNotifier(Environment* ev, FW_MNotifier* notifier)
  105. {
  106.     // create the interest for the scroll notification
  107.     FW_CInterest interest(notifier, fScrollNotificationToken);
  108.  
  109.     // Setup the connection to scroll the frame's internal transform
  110.     // This must be done before the scroller so that the frame is notified first
  111.     fView->GetFrame(ev)->AddConnection(ev, interest);    
  112.  
  113.     fConnection.AddInterest(interest);
  114. }
  115.  
  116. //----------------------------------------------------------------------------------------
  117. // FW_CScroller::UnregisterScrollNotifier
  118. //----------------------------------------------------------------------------------------
  119.  
  120. void FW_CScroller::UnregisterScrollNotifier(Environment* ev, FW_MNotifier* notifier)
  121. {
  122.     FW_CInterest interest(notifier, fScrollNotificationToken);
  123.     fConnection.RemoveInterest(interest);
  124. }
  125.  
  126. //----------------------------------------------------------------------------------------
  127. // FW_CScroller::HandleNotification
  128. //----------------------------------------------------------------------------------------
  129.  
  130. void FW_CScroller::HandleNotification(const FW_CNotification& notification)
  131. {
  132.     Environment *ev = somGetGlobalEnvironment();
  133.     
  134.     const FW_CScrollNotification& scrollNotification = (FW_CScrollNotification&) notification;
  135.     
  136.     if (scrollNotification.ShouldScroll())
  137.     {
  138.         FW_CPoint delta;
  139.         
  140.         FW_CFixed fx0 = FW_IntToFixed(0);
  141.         FW_CFixed fxDelta = scrollNotification.GetDelta();
  142.         
  143.         if (scrollNotification.GetDirection() == FW_CScrollNotification::kVertical)
  144.             delta.Set(fx0, fxDelta);
  145.         else
  146.             delta.Set(fxDelta, fx0);
  147.         
  148.         this->ScrollRelative(ev, delta);
  149.     }
  150. }
  151.  
  152. //----------------------------------------------------------------------------------------
  153. // FW_CScroller::ScrollRelative
  154. //----------------------------------------------------------------------------------------
  155.  
  156. void FW_CScroller::ScrollRelative(Environment* ev, const FW_CPoint& by)
  157. {
  158.     FW_CPoint scrollBy(-by);
  159.  
  160.     FW_CFrameFacetIterator ite(ev, fView->GetFrame(ev));
  161.     for (ODFacet* facet = (ODFacet *) ite.First(ev);
  162.             ite.IsNotComplete(ev); facet = (ODFacet *) ite.Next(ev))
  163.     {
  164.         this->ScrollDraw(ev, facet, scrollBy);
  165.     }
  166. }
  167.  
  168. //----------------------------------------------------------------------------------------
  169. // FW_CScroller::ScrollDraw
  170. //----------------------------------------------------------------------------------------
  171. //    [HLX] Need a try block
  172.  
  173. void FW_CScroller::ScrollDraw(Environment* ev, ODFacet* facet, const FW_CPoint& by)
  174. {
  175. #ifdef FW_BUILD_MAC
  176.     ODPlatformWindow platformWindow = facet->GetWindow(ev)->GetPlatformWindow(ev);
  177.     
  178.     GrafPtr port;
  179.     ::GetPort(&port);
  180.     ::SetPort(platformWindow);
  181.     Point origin;
  182.     origin.h = platformWindow->portRect.left;
  183.     origin.v = platformWindow->portRect.top;
  184.     ODRgnHandle clipRgn = ::NewRgn();
  185.     ::GetClip(clipRgn);
  186.     
  187.     ::SetOrigin(0, 0);
  188.     
  189.     // [LSD] the scroller's fView is always the ContentView for now. 
  190.     FW_CAcquiredODShape aqScrollShape = fView->GetFrame(ev)->AcquireContentScrollShape(ev, by);    
  191.  
  192.     // converts to window coordinates    
  193.     FW_CAcquiredODTransform aqWindowFrameTransform = facet->AcquireWindowFrameTransform(ev, NULL);
  194.     aqScrollShape->Transform(ev, aqWindowFrameTransform);
  195.     
  196.     FW_SPlatformRect platformRect = FW_GetShapeBoundingBox(ev, aqScrollShape);
  197.     
  198.     // get clip shape in window coordinates & intersect with scrollShape
  199.     FW_CAcquiredODShape aqAggregateClipShape = FW_CopyAndRelease(ev, facet->AcquireAggregateClipShape(ev, NULL));
  200.     aqAggregateClipShape->Transform(ev, aqWindowFrameTransform);
  201.     
  202.     aqAggregateClipShape->Intersect(ev, aqScrollShape);
  203.     
  204.     RgnHandle aggregateClipRgn = aqAggregateClipShape->GetQDRegion(ev);
  205.     ::SetClip(aggregateClipRgn);
  206.     
  207.     RgnHandle invalidRgn = ::NewRgn();    // will be adopted by aqInvalidShape. No need to dispose it
  208.     ::ScrollRect(&platformRect, by.IntX(), by.IntY(), invalidRgn);
  209.     
  210.     FW_CAcquiredODShape aqInvalidShape = ::FW_NewODShape(ev, invalidRgn);
  211.     aqInvalidShape->InverseTransform(ev, aqWindowFrameTransform);
  212.     
  213.     // ----- Validating all the embedded facets seems to make it a little bit faster
  214.     FW_CFacetIterator ite(ev, facet, kODChildrenOnly, kODFrontToBack);
  215.     for (ODFacet* embeddedFacet = ite.First(ev); ite.IsNotComplete(ev); embeddedFacet = ite.Next(ev))
  216.     {
  217.         embeddedFacet->Validate(ev, NULL, NULL);
  218.     }    
  219.  
  220.     // ----- Update the facet -----
  221.     facet->Invalidate(ev, aqInvalidShape, NULL);
  222.     facet->GetWindow(ev)->Update(ev);
  223.     
  224.     ::SetClip(clipRgn);
  225.     ::DisposeRgn(clipRgn);
  226.     ::SetOrigin(-origin.h, -origin.v);
  227.     ::SetPort(port);
  228. #endif
  229.  
  230. #ifdef FW_BUILD_WIN
  231.     FW_DEBUG_MESSAGE("Needs to be redone");
  232. #endif
  233. }
  234.  
  235. //----------------------------------------------------------------------------------------
  236. // FW_CScroller::UpdateScrollParameters
  237. //----------------------------------------------------------------------------------------
  238.  
  239. void FW_CScroller::UpdateScrollParameters(Environment* ev, FW_Boolean notify)
  240. {
  241. FW_UNUSED(ev);
  242. }
  243.  
  244. //========================================================================================
  245. // CLASS FW_CScrollBarScroller
  246. //========================================================================================
  247.  
  248. //----------------------------------------------------------------------------------------
  249. // FW_CScrollBarScroller::FW_CScrollBarScroller
  250. //----------------------------------------------------------------------------------------
  251.  
  252. FW_CScrollBarScroller::FW_CScrollBarScroller(Environment* ev, FW_CView* view,
  253.                                              FW_CScrollBar* horzSB, FW_CScrollBar* vertSB) :
  254.     FW_CScroller(ev, view),
  255.     fHorzSB(horzSB),
  256.     fVertSB(vertSB)
  257. {
  258.     if (fHorzSB)
  259.         RegisterScrollNotifier(ev, fHorzSB);
  260.     if (fVertSB)
  261.         RegisterScrollNotifier(ev, fVertSB);
  262. }
  263.  
  264. //----------------------------------------------------------------------------------------
  265. // FW_CScrollBarScroller::~FW_CScrollBarScroller
  266. //----------------------------------------------------------------------------------------
  267.  
  268. FW_CScrollBarScroller::~FW_CScrollBarScroller()
  269. {
  270.     // Don't delete the scroll bars, we don't own them! The containing gadget
  271.     // or frame owns them.
  272.     
  273.     Environment* ev = ::somGetGlobalEnvironment();
  274.     
  275.     if (fHorzSB)
  276.         UnregisterScrollNotifier(ev, fHorzSB);
  277.     if (fVertSB)
  278.         UnregisterScrollNotifier(ev, fVertSB);
  279. }
  280.  
  281. //----------------------------------------------------------------------------------------
  282. // PrivAdjustScrollBar
  283. //----------------------------------------------------------------------------------------
  284.  
  285. static FW_Boolean PrivAdjustScrollBar(Environment* ev, 
  286.                                     FW_CScrollBar* sb, 
  287.                                     FW_CFixed contentExtent, 
  288.                                     FW_CFixed scrollerSize, 
  289.                                     FW_CFixed contentOffset,
  290.                                     FW_Boolean notify)
  291. {
  292.     FW_Boolean updateAllView = FALSE;
  293.     
  294.     FW_CFixed oldPos = sb->GetScrollPos(ev);
  295.     FW_CFixed newPos;
  296.  
  297.     sb->SetMajorScrollUnits(ev, scrollerSize);
  298.     sb->SetMinorScrollUnits(ev, scrollerSize.DividedByInt(10).RoundedToInt());
  299.  
  300.     FW_CFixed range = contentExtent - scrollerSize;
  301.     if (range < FW_kFixed0)
  302.         range = FW_kFixed0;
  303.         
  304.     if (range > FW_kFixed0) {
  305.         sb->SetScrollMax(ev, sb->GetScrollMin(ev) + range);
  306.         
  307.         if (contentOffset + scrollerSize > contentExtent)
  308.             contentOffset = range;
  309.             
  310.         sb->SetScrollPos(ev, range, contentOffset);
  311.         newPos = sb->GetScrollPos(ev);
  312.     } 
  313.     else {
  314.         // scroller is bigger than content (after resizing frame for instance)
  315.         // we must scroll back to the origin
  316.         sb->SetScrollMax(ev, sb->GetScrollMin(ev));
  317.         newPos = FW_kFixed0;
  318.     }
  319.     
  320.     if (oldPos != newPos)
  321.     {
  322.         updateAllView = TRUE;
  323.         if (notify)
  324.             sb->ScrollPositionChanged(ev, newPos, newPos - oldPos, FALSE);
  325.     }
  326.  
  327.     return updateAllView;
  328. }
  329.  
  330. //----------------------------------------------------------------------------------------
  331. // FW_CScrollBarScroller::UpdateScrollParameters
  332. //----------------------------------------------------------------------------------------
  333. // [LSD] this must be corrected to handle scaling...
  334.  
  335. void FW_CScrollBarScroller::UpdateScrollParameters(Environment* ev, FW_Boolean notify)
  336. {
  337.     FW_ASSERT(fView->IsContentView(ev));    // [LSD] fView should always be the ContentView
  338.     
  339.     FW_CScroller::UpdateScrollParameters(ev);
  340.  
  341.     // Need to think about how we can provide some default behavior for updating the
  342.     // minor scroll units. [SCROLL]    
  343.     
  344.     FW_CPoint scrollerSize(fView->GetSize(ev));
  345.     
  346.     // contentOffset used to compute the scroll position is based on the Internal Transform
  347.     // minus the position of the ContentView
  348.     FW_CPoint contentOffset(FW_kZeroPoint);
  349.     fView->ViewToViewContent(ev, contentOffset);
  350.         
  351.     FW_CPoint contentExtent(fView->GetExtent(ev));        
  352.     
  353.     FW_CFrame* frame = fView->GetFrame(ev);
  354.  
  355.     FW_CScrollBar* sb = GetScrollBar(ev, kVertical);
  356.     if (sb && PrivAdjustScrollBar(ev, sb, contentExtent.y, scrollerSize.y, contentOffset.y, notify))
  357.     {
  358.         FW_CAcquiredODShape invalidShape =    frame->AcquireContentScrollShape(ev, FW_CPoint(FW_kFixed0, FW_IntToFixed(1)));
  359.         frame->GetODFrame(ev)->Invalidate(ev, invalidShape, NULL);
  360.     }
  361.     
  362.     sb = GetScrollBar(ev, kHorizontal);
  363.     if (sb && PrivAdjustScrollBar(ev, sb, contentExtent.x, scrollerSize.x, contentOffset.x, notify))
  364.     {
  365.         FW_CAcquiredODShape invalidShape =    frame->AcquireContentScrollShape(ev, FW_CPoint(FW_IntToFixed(1), FW_kFixed0));
  366.         frame->GetODFrame(ev)->Invalidate(ev, invalidShape, NULL);
  367.     }
  368. }
  369.